看到題目,題目要求我們將 password 解碼出來,提示告訴我們可以用選擇明文攻擊還有 openssl
來解密。
hint 1:Crytography Threat models: chosen plaintext attack.
hint 2:OpenSSL can be used to decrypt the message. e.g openssl enc -aes-256-cbc -d ...
hint 3:The key to getting the flag is by sending a custom message to the server by taking advantage of the RSA encryption algorithm.
hint 4:Minimum requirements for a useful cryptosystem is CPA security.
查看下載了甚麼,並用 cat
檢視題目給的 password.enc
和 secret.enc
。
$ ls -l
-rw-rw-r-- 1 peggggy-picoctf peggggy-picoctf 154 Mar 12 00:36 password.enc
-rw-rw-r-- 1 peggggy-picoctf peggggy-picoctf 64 Mar 12 00:36 secret.enc
$ cat password.enc
2336150584734702647514724021470643922433811330098144930425575029773908475892259185520495303353109615046654428965662643241365308392679139063000973730368839
$ cat secret.enc
Salted__jX9V)pT3Ͼq$qEs5n\K5=%c Q9s1!quM04
試著連上 webshell 後,發現可以加解密文字。
$ nc titan.picoctf.net 58343
*****************************************
****************THE ORACLE***************
*****************************************
what should we do for you?
E --> encrypt D --> decrypt.
E
enter text to encrypt (encoded length must be less than keysize): 123
123
encoded cleartext as Hex m: 313233
ciphertext (m ^ e mod n) 1599246634826874851095335841874633680383690362307908452095323796981689155124475346861967384109287536222761421010922720299434706521748860299773886324674588
what should we do for you?
E --> encrypt D --> decrypt.
D
Enter text to decrypt: 1599246634826874851095335841874633680383690362307908452095323796981689155124475346861967384109287536222761421010922720299434706521748860299773886324674588
decrypted ciphertext as hex (c ^ d mod n): 313233
decrypted ciphertext: 123
試著將 password 和 secret 解密,確定都沒有辦法解碼。
$ nc titan.picoctf.net 58343
*****************************************
****************THE ORACLE***************
*****************************************
what should we do for you?
E --> encrypt D --> decrypt.
D
Enter text to decrypt: 2336150584734702647514724021470643922433811330098144930425575029773908475892259185520495303353109615046654428965662643241365308392679139063000973730368839
Lol, good try, can't decrypt that for you. Be creative and good luck
what should we do for you?
E --> encrypt D --> decrypt.
D
Enter text to decrypt: Salted__jX9V)pT3Ͼq$qEs5n\K5=%c Q9s1!quM04
於是想起 hint 2,再嘗試使用 openssl
解碼 secret.enc,發現要填入 password。
於是我們從 hint1 聯想,猜測應該是要用選擇明文攻擊破解 password。
$ openssl enc -aes-256-cbc -d -in secret.enc
enter AES-256-CBC decryption password:
在要講 RSA 的 CPA ( 選擇明文攻擊 ) 前,我們先來複習 RSA。
一般 RSA 是以下步驟:
令密文 = C,明文 = M
C = M^e mod N
M = C^d mod N
那選擇明文攻擊套用在 RSA 是怎麼使用呢?首先確定我們的已知和要得到的資訊是甚麼。
我們已知密文就是得到的 password.enc 的內容,也就是 C,而我們想要知道的是 M。
然後再進行選擇明文的過程,可以參考下圖 ( 資料來源: CPA ),並且以下的 t,想像成我們欲知的 M。
簡單來說,就是選擇某個明文,並且和已知的密文相乘,一起加密,最後解密出來的內文可以推回已知密文中的明文為何。
於是可以得到底下的 pwn script。
from pwn import *
with open("password.enc") as file:
c = int(file.read())
context.log_level='critical'
p = remote("titan.picoctf.net", 61923)
p.recvuntil(b"E --> encrypt D --> decrypt.")
p.sendline(b"E")
p.recvuntil(b"(encoded length must be less than keysize): ")
# choose hex(02) as chosen plantext
p.sendline(b"\x02")
p.recvuntil(b"ciphertext (m ^ e mod n) ")
c2 = int(p.recvline())
p.recvuntil(b"E --> encrypt D --> decrypt.")
p.sendline(b"D")
p.recvuntil(b"decrypt: ")
# M^e (password.enc) * 2^e (chosen plaintext)
p.sendline(str(c * c2).encode())
p.recvuntil(b"decrypted ciphertext as hex (c ^ d mod n): ")
# p.recvuntil = M*2 mod N, and we want to get M
password = int(p.recvline(), 16) // 2
print( hex(password) )
# bytes.fromhex(str)
# hex(password)[2:], to remove '0x'
password = bytes.fromhex( hex(password)[2:]).decode('ascii')
print("Password:", password)
執行 script.py 後,會得到 password,並且依照提示 1,使用 openssl
將 secret.enc 解密,就可以得到 flag 了。
$ python3 script.py
Hex password 0x3630663530
Password: 60f50
$ openssl enc -aes-256-cbc -d -in secret.enc
enter AES-256-CBC decryption password:
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
picoCTF{su((3ss_(r@ck1ng_r3@_60f50766}
小結:
了解選擇明文攻擊。